package com.anjie.powerproject.util;

import com.anjie.powerproject.common.Constants;
import com.anjie.powerproject.config.ExecuteResult;
import com.anjie.powerproject.service.impl.EnergyModelServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.Callable;

/**
 * 自定义python执行器
 */
public class PythonExcutor {
    private static final Logger logger = LoggerFactory.getLogger(PythonExcutor.class);

    private static List<String> buildCommandList(String script, String... params) {
        List<String> commands = new ArrayList<>();
        commands.add(Constants.PYTHON_VERSION);
        commands.add(script);
        commands.addAll(Arrays.asList(params));

        return commands;
    }

    private static List<String> buildCommandList(String script, File tempFile, String... params) {
        List<String> commands = new ArrayList<>();
        commands.add(Constants.PYTHON_VERSION);
        commands.add(script);
        commands.addAll(Arrays.asList(params));
        commands.add(">");
        commands.add(tempFile.getAbsolutePath());

        return commands;
    }

    //创建能量/电量模型
    public static String runCreateScript(String script, String... params) {
        logger.info("PythonExcutor.runCreateScript()调用python文件：{}", script);
        try {
            String base = ResourceUtils.getURL("classpath:").getPath();
            ProcessBuilder builder = new ProcessBuilder().directory(new File(base + Constants.PYTHON_DIR)).command(buildCommandList(script, params));
            builder.redirectErrorStream(true);

            Process process = builder.start();
            BufferedReader buffer = new BufferedReader(new InputStreamReader(process.getInputStream()));
            StringBuilder sb = new StringBuilder();
            String line;
            while (null != (line = buffer.readLine())) {
                sb.append(line);
            }
            process.waitFor();

            String result = sb.toString();
            if (StringUtils.isNotEmpty(result)) {
                if (result.contains("PY_EXECUTE_FAIL")) {
                    logger.error(result);
                    return result;
                } else {
                    logger.info(result);
                }
            }
            return null;
        } catch (Exception e) {
            throw new RuntimeException(String.format("python脚本执行失败: %s", e.getMessage()));
        }
    }

    //生成预测数据
    public static String runPredictScript(String script, ExecuteResult executeResult, String... params) {
        logger.info("runPredictScript调用python文件：{}", script);
        try {
            String base = ResourceUtils.getURL("classpath:").getPath();
            ProcessBuilder builder = new ProcessBuilder().directory(new File(base + Constants.PYTHON_DIR)).command(buildCommandList(script, params));
            builder.redirectErrorStream(true);
            Process process = builder.start();

            String result = ((Callable<String>) () -> {
                BufferedReader buffer = new BufferedReader(new InputStreamReader(process.getInputStream()));
                StringBuilder sb = new StringBuilder();
                String line;
                try {
                    while (null != (line = (buffer.readLine()))) {
                        sb.append(line);
                        int idx = sb.lastIndexOf("PY-EXECUTE-PROCESS");
                        if (idx < 0) {
                            continue;
                        }
                        String sub = sb.substring(idx);

                        if (sub.contains("%")) {
                            String number = sub.split(":")[1].split("%")[0].trim();
                            logger.info(number);
                            executeResult.setProcess(Double.parseDouble(number));
                        } else {
                            String lastStr = sb.substring(0, idx);
                            int lastIdx = lastStr.lastIndexOf("PY-EXECUTE-PROCESS");
                            if (lastIdx < 0) {
                                continue;
                            }
                            String lastSub = lastStr.substring(lastIdx);

                            if (lastSub.contains("%")) {
                                String number = lastSub.split(":")[1].split("%")[0].trim();
                                logger.info(number);
                                executeResult.setProcess(Double.parseDouble(number));
                            }
                        }
                    }

                    buffer.close();

                    return sb.toString();
                } catch (Exception e) {
                    e.printStackTrace();
                    return "错误: " + e.getMessage();
                }
            }).call();

            process.waitFor();
            process.destroy();

            if (StringUtils.isNotEmpty(result)) {
                if (result.contains("PY_EXECUTE_FAIL")) {
                    logger.error(result);
                    return result;
                } else {
                    logger.info(result);
                }
            }
            return null;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(String.format("python脚本执行失败: %s", e.getMessage()));
        }
    }

    public static void main(String[] args) {
        ExecuteResult result = new ExecuteResult(true);
        runPredictScript("run_manual.py", result, "169", "test", "/Users/zhangxiaoye/Documents/IdeaProjects/power/target/classes/static/python/test/test_YC1008/YC1008_test1640767898285.csv");
    }
}
